#pragma once
#include <boost/variant.hpp>
#include "PaletteEntry.h"
#include "ImageData8bpp.h"
#include "ImageData16bpp.h"
#include "ImageData32bpp.h"
#include "ImageDataIndexed.h"
#include "VideoSurface.h"

namespace ja2{ namespace sgp
{
	class Rect;

	//! Image class.
	class Image : boost::noncopyable
	{
		// Enums
	public:
		//! Image transparency surface blitting flags.
		enum TransparencyBlitFlag
		{
			TBF_DEFAULT,
			TBF_TRANSPARENT,
			TBF_SHADOW,
		};

		// Attributes
	private:
		//! Image width.
		std::uint_least16_t const m_Width;
		//! Image height.
		std::uint_least16_t const m_Height;
		//! Flags.
		std::uint_least16_t const m_Flags;
		//! File name.
		std::string const m_ImageFilePath;
		//! Application data size.
		std::uint_least32_t m_AppDataSize;
		//! Application data.
		std::unique_ptr<char[]> pAppData;
		//! Image data.
		IImageDataPtr_t m_pImageData;

		// Operations
	public:
		//! Set image data.
		void set_image_data(IImageDataPtr_t &&pImageData);
		//! Get image width.
		std::uint_least16_t width() const;
		//! Get image height.
		std::uint_least16_t height() const;
		//! Create video surface from image.
		/*!
			\param SourceRect sub-image rectangle from which surface will be created.
		*/
		VideoSurfacePtr_t create_surface(IDirectDraw7Ptr pDirecDraw, VideoSurface::MemoryUsage MemUsage, TransparencyBlitFlag TransparentFlag, Rect const &SourceRect = Rect()) const;
		//! Get palette of image.
		/*!
			\return image palette (borrowed pointer) if exist, otherwise nullptr;
		*/
		PaletteVector_t const *palette() const;
		//! Create shaded palette.
		/*!
			Creates an 8 bit to 32 bit palette table, and modifies the colors as it builds.

			This can be used in several ways:
			1) To "brighten" a palette, pass down RGB values that are higher than 100% ( > 255) for all	three. mono = false.
			2) To "darken" a palette, do the same with less than 100% ( < 255) values. mono = false.
			3) To create a "glow" palette, select mono = true, and pass the color in the RGB parameters.
			4) For gamma correction, pass in weighted values for each color.

			\param RedScale
			\param GreenScale
			\param BlueScale Color mode: Percentages (255 = 100%) of color to translate into destination palette. In mono mode, color for monochrome palette.
			\param Mono true to create a monochrome palette. In mono mode, Luminance values for colors are calculated, and the RGB color is shaded according to each pixel's brightness.
		*/
		static PaletteVector_t create_palette_shaded(PaletteVector_t const &Palette, std::uint_least32_t RedScale, std::uint_least32_t GreenScale, std::uint_least32_t BlueScale, bool Mono);

		// Construction/Destruction
	public:
		Image(std::uint_least16_t Width, std::uint_least16_t Height, std::uint_least16_t Flags, std::string const &ImagePath);
	};
} /*sgp*/} /*ja2*/
